<!DOCTYPE html>
<html  lang="zh">
<head>
    <!-- hexo-inject:begin --><!-- hexo-inject:end --><meta charset="utf-8" />

<meta name="generator" content="Hexo 3.9.0" />

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />

<title>shader学习20-屏幕后处理:边缘检测 - 游戏人生</title>


    <meta name="description" content="shade学习">
<meta name="keywords" content="学习">
<meta property="og:type" content="article">
<meta property="og:title" content="shader学习20-屏幕后处理:边缘检测">
<meta property="og:url" content="http://cloundgame.gitee.io/mystudy/2020/06/28/shader学习20-屏幕后处理-边缘检测/index.html">
<meta property="og:site_name" content="游戏人生">
<meta property="og:description" content="shade学习">
<meta property="og:locale" content="zh-CN">
<meta property="og:image" content="http://cloundgame.gitee.io/mystudy/images/og_image.png">
<meta property="og:updated_time" content="2020-07-15T03:14:57.692Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="shader学习20-屏幕后处理:边缘检测">
<meta name="twitter:description" content="shade学习">
<meta name="twitter:image" content="http://cloundgame.gitee.io/mystudy/images/og_image.png">







<link rel="icon" href="/mystudy/images/favicon.svg">


<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.7.2/css/bulma.css">
<link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/font-awesome/5.9.0/css/all.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Ubuntu:400,600|Source+Code+Pro">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js@9.12.0/styles/atom-one-dark.css">


    
    
    
    <style>body>.footer,body>.navbar,body>.section{opacity:0}</style>
    

    
    
    
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/lightgallery@1.6.8/dist/css/lightgallery.min.css">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/justifiedGallery@3.7.0/dist/css/justifiedGallery.min.css">
    

    
    

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/outdatedbrowser@1.1.5/outdatedbrowser/outdatedbrowser.min.css">


    
    
    
    

<link rel="stylesheet" href="/mystudy/css/back-to-top.css">


    
    

    
    
    
    

    
    
<link rel="stylesheet" href="/mystudy/css/progressbar.css">
<script src="https://cdn.jsdelivr.net/npm/pace-js@1.0.2/pace.min.js"></script>

    
    
    
        <script async="" src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
    

    


<link rel="stylesheet" href="/mystudy/css/style.css"><!-- hexo-inject:begin --><!-- hexo-inject:end -->
</head>
<body class="is-3-column">
    <!-- hexo-inject:begin --><!-- hexo-inject:end --><nav class="navbar navbar-main">
    <div class="container">
        <div class="navbar-brand is-flex-center">
            <a class="navbar-item navbar-logo" href="/mystudy/">
            
                <img src="/mystudy/images/logo.svg" alt="shader学习20-屏幕后处理:边缘检测" height="28">
            
            </a>
        </div>
        <div class="navbar-menu">
            
            <div class="navbar-start">
                
                <a class="navbar-item"
                href="/mystudy/">主页</a>
                
                <a class="navbar-item"
                href="/mystudy/archives">日志</a>
                
                <a class="navbar-item"
                href="/mystudy/categories">分类</a>
                
                <a class="navbar-item"
                href="/mystudy/">关于</a>
                
            </div>
            
            <div class="navbar-end">
                
                    
                    
                    <a class="navbar-item" target="_blank" title="Download on GitHub" href="https://github.com/koliy/koliy.github.io">
                        
                        <i class="fab fa-github"></i>
                        
                    </a>
                    
                
                
                <a class="navbar-item is-hidden-tablet catalogue" title="目录" href="javascript:;">
                    <i class="fas fa-list-ul"></i>
                </a>
                
                
                <a class="navbar-item search" title="搜索" href="javascript:;">
                    <i class="fas fa-search"></i>
                </a>
                
            </div>
        </div>
    </div>
</nav>
    
    <section class="section">
        <div class="container">
            <div class="columns">
                <div class="column is-8-tablet is-8-desktop is-6-widescreen has-order-2 column-main"><div class="card">
    
    <div class="card-content article ">
        
        <div class="level article-meta is-size-7 is-uppercase is-mobile is-overflow-x-auto">
            <div class="level-left">
                <time class="level-item has-text-grey" datetime="2020-06-28T06:29:50.000Z">2020-06-28</time>
                
                <div class="level-item">
                <a class="has-link-grey -link" href="/mystudy/categories/shade学习/">shade学习</a>
                </div>
                
                
                <span class="level-item has-text-grey">
                    
                    
                    15 分钟 读完 (大约 2176 个字)
                </span>
                
                
                <span class="level-item has-text-grey" id="busuanzi_container_page_pv">
                    <i class="far fa-eye"></i>
                    <span id="busuanzi_value_page_pv">0</span>次访问
                </span>
                
            </div>
        </div>
        
        <h1 class="title is-size-3 is-size-4-mobile has-text-weight-normal">
            
                shader学习20-屏幕后处理:边缘检测
            
        </h1>
        <div class="content">
            <h2 id="边缘检测"><a href="#边缘检测" class="headerlink" title="边缘检测"></a><strong>边缘检测</strong></h2><p>边缘检测是描边效果的一种实现方法.</p>
<a id="more"></a>
<ul>
<li><strong>边缘检测的原理就是利用一些边缘检测算子对图像进行卷积操作</strong></li>
</ul>
<h2 id="卷积"><a href="#卷积" class="headerlink" title="卷积"></a><strong>卷积</strong></h2><p>在图像处理中，卷积操作指的就是使用一个卷积核对一张图像中的每个像素进行一系列操作。</p>
<h4 id="线性滤波"><a href="#线性滤波" class="headerlink" title="线性滤波"></a><strong>线性滤波</strong></h4><p>在数字图像处理中，有一种基本的处理方法:线性滤波,待处理的平面数字图像可被看做一个大矩阵，图像的每个像素对应着矩阵的每个元素.<br>用于滤波的是一个滤波器小矩阵,也叫卷积核.</p>
<h4 id="卷积核"><a href="#卷积核" class="headerlink" title="卷积核"></a><strong>卷积核</strong></h4><p>卷积核通常是一个四方形网格结构(2x2,3x3),比如Sobel算子，就是2个3x3的小矩阵。</p>
<ul>
<li><strong>进行滤波就是对于大矩阵中的每个像素，计算它周围像素和滤波器矩阵对应位置元素的乘积，然后把结果相加到一起，最终得到的值就作为该像素的新值，这样完成了一次滤波.</strong></li>
</ul>
<p><img src="unity1.png" alt></p>
<p><em>由图可知，用卷积核的中心对准了，图像单个元素，然后计算它周围像素和卷积核矩阵对应位置的乘积。没有对应位置的元素为0作乘积</em></p>
<h4 id="边缘检测算子"><a href="#边缘检测算子" class="headerlink" title="边缘检测算子"></a><strong>边缘检测算子</strong></h4><ul>
<li><strong>边到底是如何形成的?</strong><br>如果相邻像素之间存在差别明显的颜色，亮度，纹理等属性，我们就会认为它们之间应该有一条边界。</li>
</ul>
<h4 id="Sobel算子"><a href="#Sobel算子" class="headerlink" title="Sobel算子"></a><strong>Sobel算子</strong></h4><p>也叫Sobel滤波，是2个3*3的矩阵，主要用来计算图像单个像素在横向/纵向上的梯度。<br>Sobel算子可以用来对图像进行边缘检测，或者用来计算某个像素点的法线向量。</p>
<p>$$<br>G_{x}=\begin{bmatrix} -1&amp;-2&amp;-1\\0&amp;0&amp;0\\1&amp;2&amp;1\end{bmatrix}<br>$$</p>
<p>$$<br>G_{y}=\begin{bmatrix} -1&amp;0&amp;1\\-2&amp;0&amp;2\\-1&amp;0&amp;1\end{bmatrix}<br>$$</p>
<p>分别用于检测水平方向和竖直方向上的边缘信息，在进行边缘检测时，需要对每个像素分别进行一次卷积计算，得到2个方向上的梯度值$G_{x}$和$G_{y}$，将其结果相加:<br>$$ |G| = \sqrt{G_{x}^2+G_{y}^2} $$</p>
<p>由于包含开根号操作，出于性能考虑，使用绝对值操作代替开根号:<br>$$ G = |G_{x}| + |G_{y}| $$<br>通过判断G是否大于一个定值，我们就能判断这个像素是否属于边缘(G越大，越有可能是边缘点)</p>
<figure class="highlight javascript hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br></pre></td><td class="code"><pre><span class="line">Shader<span class="hljs-string">"MyTest/Test7/testSobel"</span>&#123;</span><br><span class="line">	Properties&#123;</span><br><span class="line">		_MainTex(<span class="hljs-string">"Main Tex"</span>,<span class="hljs-number">2</span>D)=<span class="hljs-string">"white"</span>&#123;&#125;</span><br><span class="line">		_EdgeOnly(<span class="hljs-string">"Edge Only"</span>,float)=<span class="hljs-number">1.0</span></span><br><span class="line">		_EdgeColor(<span class="hljs-string">"Edge Color"</span>,Color)=(<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,<span class="hljs-number">1</span>)</span><br><span class="line">		_BackgroundColor(<span class="hljs-string">"BG Color"</span>,Color)=(<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,<span class="hljs-number">1</span>)</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	SubShader&#123;</span><br><span class="line">		ZTest Always </span><br><span class="line">		Cull Off</span><br><span class="line">		Zwrite Off</span><br><span class="line"></span><br><span class="line">		Pass&#123;</span><br><span class="line">			Tags&#123;<span class="hljs-string">"LightMode"</span>=<span class="hljs-string">"ForwardBase"</span>&#125;</span><br><span class="line"></span><br><span class="line">			CGPROGRAM</span><br><span class="line">			#include "Lighting.cginc"</span><br><span class="line">			#include "UnityCG.cginc"</span><br><span class="line"></span><br><span class="line">			#pragma multi_compile_fwdbase</span><br><span class="line">			#pragma vertex vert</span><br><span class="line">			#pragma fragment fragSobel</span><br><span class="line"></span><br><span class="line">			sampler2D _MainTex;</span><br><span class="line">			<span class="hljs-comment">//xxx_TexelSize是Unity为我们提供的访问xxx纹理对应的每个纹素的大小，如1/512</span></span><br><span class="line">			half4 _MainTex_TexelSize;</span><br><span class="line"></span><br><span class="line">			half _EdgeOnly;</span><br><span class="line">			fixed4 _EdgeColor;</span><br><span class="line">			fixed4 _BackgroundColor;</span><br><span class="line"></span><br><span class="line">			struct a2v&#123;</span><br><span class="line">				float4 vertex:POSITION;</span><br><span class="line">				float4 texcoord:TEXCOORD0;</span><br><span class="line">			&#125;;</span><br><span class="line"></span><br><span class="line">			struct v2f&#123;</span><br><span class="line">				float4 pos:SV_POSITION;</span><br><span class="line">				half2 uv[<span class="hljs-number">9</span>]:TEXCOORD0;</span><br><span class="line">				</span><br><span class="line">			&#125;;</span><br><span class="line"></span><br><span class="line">			v2f vert(a2v v)&#123;</span><br><span class="line">				v2f o;</span><br><span class="line">				o.pos = UnityObjectToClipPos(v.vertex);</span><br><span class="line">				<span class="hljs-comment">//获取该像素点周围像素</span></span><br><span class="line">				half2 uv = v.texcoord;</span><br><span class="line">				<span class="hljs-comment">//当前像素相邻左下角位置像素值</span></span><br><span class="line">				o.uv[<span class="hljs-number">0</span>] = uv + _MainTex_TexelSize.xy * half2(<span class="hljs-number">-1</span>,<span class="hljs-number">-1</span>);</span><br><span class="line">				o.uv[<span class="hljs-number">1</span>] = uv + _MainTex_TexelSize.xy * half2(<span class="hljs-number">0</span>,<span class="hljs-number">-1</span>); <span class="hljs-comment">//下边</span></span><br><span class="line">				o.uv[<span class="hljs-number">2</span>] = uv + _MainTex_TexelSize.xy * half2(<span class="hljs-number">1</span>,<span class="hljs-number">-1</span>); <span class="hljs-comment">//右下角</span></span><br><span class="line">				o.uv[<span class="hljs-number">3</span>] = uv + _MainTex_TexelSize.xy * half2(<span class="hljs-number">-1</span>,<span class="hljs-number">0</span>); <span class="hljs-comment">//左边</span></span><br><span class="line">				o.uv[<span class="hljs-number">4</span>] = uv + _MainTex_TexelSize.xy * half2(<span class="hljs-number">0</span>,<span class="hljs-number">0</span>); <span class="hljs-comment">//原点，本像素</span></span><br><span class="line">				o.uv[<span class="hljs-number">5</span>] = uv + _MainTex_TexelSize.xy * half2(<span class="hljs-number">1</span>,<span class="hljs-number">0</span>); <span class="hljs-comment">//右边</span></span><br><span class="line">				o.uv[<span class="hljs-number">6</span>] = uv + _MainTex_TexelSize.xy * half2(<span class="hljs-number">-1</span>,<span class="hljs-number">1</span>); <span class="hljs-comment">//左上角</span></span><br><span class="line">				o.uv[<span class="hljs-number">7</span>] = uv + _MainTex_TexelSize.xy * half2(<span class="hljs-number">0</span>,<span class="hljs-number">1</span>); <span class="hljs-comment">//上面</span></span><br><span class="line">				o.uv[<span class="hljs-number">8</span>] = uv + _MainTex_TexelSize.xy * half2(<span class="hljs-number">1</span>,<span class="hljs-number">1</span>); <span class="hljs-comment">//右上角</span></span><br><span class="line"></span><br><span class="line">				<span class="hljs-keyword">return</span> o;</span><br><span class="line">			&#125;</span><br><span class="line">		</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">			<span class="hljs-comment">//计算该纹素的饱和度值</span></span><br><span class="line">			fixed luminance (fixed4 color)&#123;</span><br><span class="line">				<span class="hljs-keyword">return</span> <span class="hljs-number">0.2125</span> * color.r + <span class="hljs-number">0.7154</span> * color.g + <span class="hljs-number">0.0721</span> * color.b;</span><br><span class="line">			&#125;</span><br><span class="line"></span><br><span class="line">			half Sobel(v2f i)&#123;</span><br><span class="line">				<span class="hljs-keyword">const</span> half Gx[<span class="hljs-number">9</span>] = &#123;</span><br><span class="line">					<span class="hljs-number">-1</span>,<span class="hljs-number">-2</span>,<span class="hljs-number">-1</span>,</span><br><span class="line">					<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,</span><br><span class="line">					<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">1</span></span><br><span class="line">				&#125;;</span><br><span class="line">				<span class="hljs-keyword">const</span> half Gy[<span class="hljs-number">9</span>]=&#123;</span><br><span class="line">					<span class="hljs-number">-1</span>,<span class="hljs-number">0</span>,<span class="hljs-number">1</span>,</span><br><span class="line">					<span class="hljs-number">-2</span>,<span class="hljs-number">0</span>,<span class="hljs-number">2</span>,</span><br><span class="line">					<span class="hljs-number">-1</span>,<span class="hljs-number">0</span>,<span class="hljs-number">1</span></span><br><span class="line">				&#125;;</span><br><span class="line"></span><br><span class="line">				half texColor;</span><br><span class="line">				half edgeX = <span class="hljs-number">0</span>;</span><br><span class="line">				half edgeY = <span class="hljs-number">0</span>;</span><br><span class="line">				<span class="hljs-comment">//对该元素的相邻像素进行Sobel卷积计算</span></span><br><span class="line">				<span class="hljs-keyword">for</span>(int it =<span class="hljs-number">0</span>;it&lt;<span class="hljs-number">9</span>;it++)&#123;</span><br><span class="line">					<span class="hljs-comment">//先获取饱和度值</span></span><br><span class="line">					texColor = luminance(tex2D(_MainTex,i.uv[it]));</span><br><span class="line">					<span class="hljs-comment">//计算横纵方向的梯度</span></span><br><span class="line">					edgeX += texColor * Gx[it];</span><br><span class="line">					edgeY += texColor * Gy[it];</span><br><span class="line">				&#125;</span><br><span class="line">				<span class="hljs-comment">//edge值越小，表明横纵方向梯度值越大，该位置越可能是边缘点</span></span><br><span class="line">				half edge = <span class="hljs-number">1</span> - abs(edgeX ) - abs(edgeY);</span><br><span class="line">				<span class="hljs-keyword">return</span> edge;</span><br><span class="line">			&#125;</span><br><span class="line"></span><br><span class="line">						</span><br><span class="line">			fixed4 fragSobel(v2f i):SV_Target&#123;</span><br><span class="line">				half edge = Sobel(i);</span><br><span class="line">				<span class="hljs-comment">//edge值越小，表明梯度越大，该点更可能是边界</span></span><br><span class="line">				fixed4 withEdgeColor = lerp(_EdgeColor,tex2D(_MainTex,i.uv[<span class="hljs-number">4</span>]),edge);</span><br><span class="line">				<span class="hljs-comment">//描边和背景色进行混合差值</span></span><br><span class="line">				fixed4 onlyEdgeColor = lerp(_EdgeColor,_BackgroundColor,edge);</span><br><span class="line">				<span class="hljs-keyword">return</span> lerp(withEdgeColor,onlyEdgeColor,_EdgeOnly);</span><br><span class="line">			&#125;</span><br><span class="line">			ENDCG</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<ul>
<li><p><strong>_MainTex_TexelSize</strong><br>unity为我们梯度访问xxx纹理的每个纹素的大小，如1/512,由于卷积需要对相邻区域内的纹素进行采样，因此需要利用TexelSize来计算各个相邻区域的纹理坐标。</p>
</li>
<li><p><strong>half2 uv[9]:TEXCOORD0</strong><br>定义一个维数为9的纹理数组。通过把计算采样纹理坐标的代码从片元中转移到顶点中，可以减少运算，提高性能。由于lerp是线性的，因此不影响纹理坐标的计算结果。</p>
</li>
<li><p><strong>控制描边大小</strong></p>
<figure class="highlight javascript hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">float2 adjacentPixel = _MainTex_TexelSize.xy * _EdgeSize;</span><br><span class="line"></span><br><span class="line"><span class="hljs-comment">//当前像素相邻左下角位置像素值</span></span><br><span class="line">o.uv[<span class="hljs-number">0</span>] = uv + adjacentPixel * half2(<span class="hljs-number">-1</span>,<span class="hljs-number">-1</span>);</span><br><span class="line">o.uv[<span class="hljs-number">1</span>] = uv + adjacentPixel * half2(<span class="hljs-number">0</span>,<span class="hljs-number">-1</span>); <span class="hljs-comment">//下边</span></span><br><span class="line">o.uv[<span class="hljs-number">2</span>] = uv + adjacentPixel * half2(<span class="hljs-number">1</span>,<span class="hljs-number">-1</span>); <span class="hljs-comment">//右下角</span></span><br><span class="line">o.uv[<span class="hljs-number">3</span>] = uv + adjacentPixel * half2(<span class="hljs-number">-1</span>,<span class="hljs-number">0</span>); <span class="hljs-comment">//左边</span></span><br><span class="line">o.uv[<span class="hljs-number">4</span>] = uv + adjacentPixel * half2(<span class="hljs-number">0</span>,<span class="hljs-number">0</span>); <span class="hljs-comment">//原点，本像素</span></span><br><span class="line">o.uv[<span class="hljs-number">5</span>] = uv + adjacentPixel * half2(<span class="hljs-number">1</span>,<span class="hljs-number">0</span>); <span class="hljs-comment">//右边</span></span><br><span class="line">o.uv[<span class="hljs-number">6</span>] = uv + adjacentPixel * half2(<span class="hljs-number">-1</span>,<span class="hljs-number">1</span>); <span class="hljs-comment">//左上角</span></span><br><span class="line">o.uv[<span class="hljs-number">7</span>] = uv + adjacentPixel * half2(<span class="hljs-number">0</span>,<span class="hljs-number">1</span>); <span class="hljs-comment">//上面</span></span><br><span class="line">o.uv[<span class="hljs-number">8</span>] = uv + adjacentPixel * half2(<span class="hljs-number">1</span>,<span class="hljs-number">1</span>); <span class="hljs-comment">//右上角</span></span><br></pre></td></tr></table></figure>

</li>
</ul>
<h4 id="Laplacian算子"><a href="#Laplacian算子" class="headerlink" title="Laplacian算子"></a><strong>Laplacian算子</strong></h4><p>拉普拉斯算子只要进行一次卷积，比起Sobel方便一点，只需要一个卷积核就能检测边缘，其缺点是对噪声比较敏感，可能会有很多噪点。</p>
<p>$$<br>\begin{bmatrix} 0&amp;1&amp;0\\1&amp;-4&amp;1\\0&amp;1&amp;0\end{bmatrix}<br>$$</p>
<h2 id="利用深度和法线纹理进行描边"><a href="#利用深度和法线纹理进行描边" class="headerlink" title="利用深度和法线纹理进行描边"></a><strong>利用深度和法线纹理进行描边</strong></h2><p>Sobel算子对屏幕图像进行边缘检测，这种利用颜色信息进行边缘检测的方法会产生很多我们不希望得到的边缘线:物体的纹理，阴影等位置也被描上黑边，这不是我们希望看到的。<br>使用深度和法线纹理进行边缘检测，这些图像不会受纹理和光照的影响，而仅仅保存了当前渲染物体的模型信息，边缘更加可靠.</p>
<h4 id="Roberts算子"><a href="#Roberts算子" class="headerlink" title="Roberts算子"></a><strong>Roberts算子</strong></h4><p><strong>Roberts算子的本质就是计算左上角和右下角的差值，乘以右上角和左下角的差值，作为边缘的依据.</strong><br>这里以深度和法线纹理的坐标，以类似Roberts算子的方式，进行对角线差值计算。</p>
<p>$$<br>G_{x}=\begin{bmatrix} -1&amp;0\\0&amp;1\end{bmatrix}<br>$$</p>
<p>$$<br>G_{y}=\begin{bmatrix} 0&amp;-1\\1&amp;0\end{bmatrix}<br>$$</p>
<figure class="highlight javascript hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="hljs-comment">//右上角</span></span><br><span class="line">o.uv[<span class="hljs-number">1</span>] = uv +_MainTex_TexelSize.xy * half2(<span class="hljs-number">1</span>,<span class="hljs-number">1</span>)*_SampleDistance;</span><br><span class="line"><span class="hljs-comment">//左下角</span></span><br><span class="line">o.uv[<span class="hljs-number">1</span>] = uv +_MainTex_TexelSize.xy * half2(<span class="hljs-number">-1</span>,<span class="hljs-number">-1</span>)*_SampleDistance;</span><br><span class="line"><span class="hljs-comment">//左上角</span></span><br><span class="line">o.uv[<span class="hljs-number">1</span>] = uv +_MainTex_TexelSize.xy * half2(<span class="hljs-number">-1</span>,<span class="hljs-number">1</span>)*_SampleDistance;</span><br><span class="line"><span class="hljs-comment">//右下角</span></span><br><span class="line">o.uv[<span class="hljs-number">1</span>] = uv +_MainTex_TexelSize.xy * half2(<span class="hljs-number">1</span>,<span class="hljs-number">-1</span>)*_SampleDistance;</span><br></pre></td></tr></table></figure>

<figure class="highlight javascript hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line">public float edgeOnly = <span class="hljs-number">0</span>f;</span><br><span class="line">    public Color edgeColor = Color.black;</span><br><span class="line">    public Color backgroundColor = Color.white;</span><br><span class="line">    <span class="hljs-comment">//控制采样距离，描边宽度大小</span></span><br><span class="line">    public float sampleDistance = <span class="hljs-number">1.0</span>f;</span><br><span class="line">    <span class="hljs-comment">//depth和normal差值的大小，会被认为存在一条边界,对应法线和深度的检测灵敏度</span></span><br><span class="line">    public float sensitivityDepth = <span class="hljs-number">1.0</span>f;</span><br><span class="line">    public float sensitivityNormal = <span class="hljs-number">1.0</span>f;</span><br><span class="line"></span><br><span class="line">    <span class="hljs-keyword">void</span> OnEnable()</span><br><span class="line">    &#123;</span><br><span class="line">        MyCamera.depthTextureMode |= DepthTextureMode.DepthNormals;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="hljs-comment">//不对透明物体产生影响</span></span><br><span class="line">    [ImageEffectOpaque]</span><br><span class="line">    <span class="hljs-keyword">void</span> OnRenderImage(RenderTexture src, RenderTexture dest)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="hljs-keyword">if</span> (material != <span class="hljs-literal">null</span>)</span><br><span class="line">        &#123;</span><br><span class="line">            material.SetFloat(<span class="hljs-string">"_EdgeOnly"</span>, edgeOnly);</span><br><span class="line">            material.SetColor(<span class="hljs-string">"_EdgeColor"</span>, edgeColor);</span><br><span class="line">            material.SetColor(<span class="hljs-string">"_BackgroundColor"</span>, backgroundColor);</span><br><span class="line">            material.SetFloat(<span class="hljs-string">"_SampleDistance"</span>, sampleDistance);</span><br><span class="line">            material.SetVector(<span class="hljs-string">"_Sensitivity"</span>, <span class="hljs-keyword">new</span> Vector4(sensitivityNormal, sensitivityDepth, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>));</span><br><span class="line"></span><br><span class="line">            Graphics.Blit(src, dest, material);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="hljs-keyword">else</span></span><br><span class="line">        &#123;</span><br><span class="line">            Graphics.Blit(src, dest);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight javascript hljs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br></pre></td><td class="code"><pre><span class="line">Shader <span class="hljs-string">"MyTest/Test7/test7-testEdge"</span></span><br><span class="line">&#123;</span><br><span class="line">	Properties</span><br><span class="line">	&#123;</span><br><span class="line">		_MainTex (<span class="hljs-string">"Texture"</span>, <span class="hljs-number">2</span>D) = <span class="hljs-string">"white"</span> &#123;&#125;</span><br><span class="line">		_EdgeOnly(<span class="hljs-string">"Edge only"</span>,Float)=<span class="hljs-number">1</span></span><br><span class="line">		_EdgeColor(<span class="hljs-string">"Edge Color"</span>,Color)=(<span class="hljs-number">1</span>,<span class="hljs-number">1</span>,<span class="hljs-number">1</span>,<span class="hljs-number">1</span>)</span><br><span class="line">		_BackgroundColor(<span class="hljs-string">"_BackgroundColor Color"</span>,Color)=(<span class="hljs-number">1</span>,<span class="hljs-number">1</span>,<span class="hljs-number">1</span>,<span class="hljs-number">1</span>)</span><br><span class="line">		_SampleDistance(<span class="hljs-string">"_SampleDistance only"</span>,Float)=<span class="hljs-number">1</span></span><br><span class="line">		_Sensitivity(<span class="hljs-string">"_Sensitivity"</span>,Vector)=(<span class="hljs-number">1</span>,<span class="hljs-number">1</span>,<span class="hljs-number">1</span>,<span class="hljs-number">1</span>)</span><br><span class="line"></span><br><span class="line">	&#125;</span><br><span class="line">	SubShader</span><br><span class="line">	&#123;</span><br><span class="line">		Tags &#123; <span class="hljs-string">"RenderType"</span>=<span class="hljs-string">"Opaque"</span> &#125;</span><br><span class="line">	</span><br><span class="line">		CGINCLUDE</span><br><span class="line">		#include "UnityCG.cginc"</span><br><span class="line"></span><br><span class="line">		sampler2D _MainTex;</span><br><span class="line">		half4 _MainTex_TexelSize;</span><br><span class="line">		fixed _EdgeOnly;</span><br><span class="line">		fixed4 _EdgeColor;</span><br><span class="line">		fixed4 _BackgroundColor;</span><br><span class="line">		float _SampleDistance;</span><br><span class="line">		half4 _Sensitivity;</span><br><span class="line"></span><br><span class="line">		sampler2D _CameraDepthNormalsTexture;</span><br><span class="line"></span><br><span class="line">		struct v2f&#123;</span><br><span class="line">			float4 pos:SV_POSITION;</span><br><span class="line">			half2 uv[<span class="hljs-number">5</span>]:TEXCOORD0;</span><br><span class="line">		&#125;;</span><br><span class="line"></span><br><span class="line">		v2f vert(appdata_img v)&#123;</span><br><span class="line">			v2f o;</span><br><span class="line">			o.pos = UnityObjectToClipPos(v.vertex);</span><br><span class="line">			half2 uv = v.texcoord;</span><br><span class="line">			o.uv[<span class="hljs-number">0</span>] = uv;</span><br><span class="line"></span><br><span class="line">			#if UNITY_UV_STARTS_AT_TOP</span><br><span class="line">				<span class="hljs-keyword">if</span>(_MainTex_TexelSize.y &lt; <span class="hljs-number">0</span>)&#123;</span><br><span class="line">					uv.y = <span class="hljs-number">1</span>- uv.y;</span><br><span class="line">				&#125;</span><br><span class="line">			#endif</span><br><span class="line">			<span class="hljs-comment">//右上角</span></span><br><span class="line">			o.uv[<span class="hljs-number">1</span>] = uv +_MainTex_TexelSize.xy * half2(<span class="hljs-number">1</span>,<span class="hljs-number">1</span>)*_SampleDistance;</span><br><span class="line">			<span class="hljs-comment">//左下角</span></span><br><span class="line">			o.uv[<span class="hljs-number">2</span>] = uv +_MainTex_TexelSize.xy * half2(<span class="hljs-number">-1</span>,<span class="hljs-number">-1</span>)*_SampleDistance;</span><br><span class="line">			<span class="hljs-comment">//左上角</span></span><br><span class="line">			o.uv[<span class="hljs-number">3</span>] = uv +_MainTex_TexelSize.xy * half2(<span class="hljs-number">-1</span>,<span class="hljs-number">1</span>)*_SampleDistance;</span><br><span class="line">			<span class="hljs-comment">//右下角</span></span><br><span class="line">			o.uv[<span class="hljs-number">4</span>] = uv +_MainTex_TexelSize.xy * half2(<span class="hljs-number">1</span>,<span class="hljs-number">-1</span>)*_SampleDistance;</span><br><span class="line"></span><br><span class="line">			<span class="hljs-keyword">return</span> o;</span><br><span class="line">		&#125;</span><br><span class="line"></span><br><span class="line">		half CheckSame(half4 center ,half4 sample)&#123;</span><br><span class="line">			<span class="hljs-comment">//这里只需要比较2个采样值的差异度，并不需要知道它们真正的法线值</span></span><br><span class="line">			half2 centerNormal = center.xy;</span><br><span class="line">			<span class="hljs-comment">//获取深度值(0,1)</span></span><br><span class="line">			float centerDepth = DecodeFloatRG(center.zw);</span><br><span class="line">			half2 sampleNormal = sample.xy;</span><br><span class="line">			float sampleDepth = DecodeFloatRG(sample.zw);</span><br><span class="line"></span><br><span class="line">			half2 diffNormal = abs(centerNormal - sampleNormal) * _Sensitivity.x;</span><br><span class="line">			<span class="hljs-comment">//法线差值，差值大于0.1判断为变换明显，作为边</span></span><br><span class="line">			int isSameNormal = (diffNormal.x + diffNormal.y)&lt; <span class="hljs-number">0.1</span>;</span><br><span class="line"></span><br><span class="line">			float diffDepth = abs(centerDepth - sampleDepth) * _Sensitivity.y;</span><br><span class="line">			<span class="hljs-comment">// 深度差值，差值大于0.1判断为变换明显，作为边。</span></span><br><span class="line">			int isSameDepth = diffDepth &lt; <span class="hljs-number">0.1</span>* centerDepth;</span><br><span class="line"></span><br><span class="line">			<span class="hljs-comment">// 法线 或 深度 其中一个相差大（为0）就是边</span></span><br><span class="line">			<span class="hljs-keyword">return</span> isSameNormal * isSameDepth ? <span class="hljs-number">1.0</span>:<span class="hljs-number">0</span>;</span><br><span class="line">		&#125;</span><br><span class="line"></span><br><span class="line">		fixed4 frag(v2f i):SV_Target&#123;</span><br><span class="line">			<span class="hljs-comment">//对角领域采样</span></span><br><span class="line">			half4 sample1 = tex2D(_CameraDepthNormalsTexture,i.uv[<span class="hljs-number">1</span>]);</span><br><span class="line">			half4 sample2 = tex2D(_CameraDepthNormalsTexture,i.uv[<span class="hljs-number">2</span>]);</span><br><span class="line">			half4 sample3 = tex2D(_CameraDepthNormalsTexture,i.uv[<span class="hljs-number">3</span>]);</span><br><span class="line">			half4 sample4 = tex2D(_CameraDepthNormalsTexture,i.uv[<span class="hljs-number">4</span>]);</span><br><span class="line"></span><br><span class="line">			half edge =<span class="hljs-number">1</span>;</span><br><span class="line">			</span><br><span class="line">			edge *= CheckSame(sample1,sample2);</span><br><span class="line">			edge *= CheckSame(sample3,sample4);</span><br><span class="line">			fixed4 withEdgeColor = lerp(_EdgeColor,tex2D(_MainTex,i.uv[<span class="hljs-number">0</span>]),edge);</span><br><span class="line">			fixed4 onlyEdgeColor = lerp(_EdgeColor,_BackgroundColor,edge);</span><br><span class="line"></span><br><span class="line">			<span class="hljs-keyword">return</span> lerp(withEdgeColor,onlyEdgeColor,_EdgeOnly);</span><br><span class="line"></span><br><span class="line">		&#125;</span><br><span class="line"></span><br><span class="line">		ENDCG</span><br><span class="line">	</span><br><span class="line">		Pass&#123;</span><br><span class="line">			ZTest Always</span><br><span class="line">			Cull Off</span><br><span class="line">			ZWrite Off</span><br><span class="line"></span><br><span class="line">			CGPROGRAM</span><br><span class="line">			#pragma vertex vert</span><br><span class="line">			#pragma fragment frag</span><br><span class="line">			ENDCG</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="法线外扩描边"><a href="#法线外扩描边" class="headerlink" title="法线外扩描边"></a><strong>法线外扩描边</strong></h2>
        </div>
        
        <div class="level is-size-7 is-uppercase">
            <div class="level-start">
                <div class="level-item">
                    <span class="is-size-6 has-text-grey has-mr-7">#</span>
                    <a class="has-link-grey -link" href="/mystudy/tags/学习/">学习</a>
                </div>
            </div>
        </div>
        
        

        
        <div class="social-share"></div>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/social-share.js@1.0.16/dist/css/share.min.css">
<script src="https://cdn.jsdelivr.net/npm/social-share.js@1.0.16/dist/js/social-share.min.js"></script>
        
    </div>
</div>





<div class="card card-transparent">
    <div class="level post-navigation is-flex-wrap is-mobile">
        
        <div class="level-start">
            <a class="level level-item has-link-grey  article-nav-prev" href="/mystudy/2020/06/28/shader学习20-屏幕后处理-高斯模糊/">
                <i class="level-item fas fa-chevron-left"></i>
                <span class="level-item">shader学习20-屏幕后处理:高斯模糊</span>
            </a>
        </div>
        
        
        <div class="level-end">
            <a class="level level-item has-link-grey  article-nav-next" href="/mystudy/2020/06/28/shader学习20-屏幕后处理-屏幕亮度-饱和度和对比度/">
                <span class="level-item">shader学习20-屏幕后处理:屏幕亮度,饱和度和对比度</span>
                <i class="level-item fas fa-chevron-right"></i>
            </a>
        </div>
        
    </div>
</div>


</div>
                




<div class="column is-4-tablet is-4-desktop is-3-widescreen  has-order-1 column-left ">
    
        
<div class="card widget">
    <div class="card-content">
        <nav class="level">
            <div class="level-item has-text-centered" style="flex-shrink: 1">
                <div>
                    
                        <img class="image is-128x128 has-mb-6" src="/mystudy/images/avatar2.jpg" alt="满头大汉老黄牛">
                    
                    
                    <p class="is-size-4 is-block">
                        满头大汉老黄牛
                    </p>
                    
                    
                    <p class="is-size-6 is-block">
                        游戏
                    </p>
                    
                    
                    <p class="is-size-6 is-flex is-flex-center has-text-grey">
                        <i class="fas fa-map-marker-alt has-mr-7"></i>
                        <span>火星</span>
                    </p>
                    
                </div>
            </div>
        </nav>
        <nav class="level is-mobile">
            <div class="level-item has-text-centered is-marginless">
                <div>
                    <p class="heading">
                        文章
                    </p>
                    <p class="title has-text-weight-normal">
                        70
                    </p>
                </div>
            </div>
            <div class="level-item has-text-centered is-marginless">
                <div>
                    <p class="heading">
                        分类
                    </p>
                    <p class="title has-text-weight-normal">
                        10
                    </p>
                </div>
            </div>
            <div class="level-item has-text-centered is-marginless">
                <div>
                    <p class="heading">
                        标签
                    </p>
                    <p class="title has-text-weight-normal">
                        3
                    </p>
                </div>
            </div>
        </nav>
        <div class="level">
            <a class="level-item button is-link is-rounded" href="https://github.com/koliy/" target="_blank">
                关注我</a>
        </div>
        
        
        <div class="level is-mobile">
            
            <a class="level-item button is-white is-marginless" target="_blank"
                title="Github" href="https://github.com/koliy/">
                
                <i class="fab fa-github"></i>
                
            </a>
            
        </div>
        
    </div>
</div>
    
        


    
        
<div class="card widget">
    <div class="card-content">
        <div class="menu">
            <h3 class="menu-label">
                分类
            </h3>
            <ul class="menu-list">
            <li>
        <a class="level is-marginless" href="/mystudy/categories/3D数学基础-图形与游戏开发/">
            <span class="level-start">
                <span class="level-item">3D数学基础:图形与游戏开发</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">3</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/mystudy/categories/AI/">
            <span class="level-start">
                <span class="level-item">AI</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">12</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/mystudy/categories/MySql/">
            <span class="level-start">
                <span class="level-item">MySql</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/mystudy/categories/SurfaceShader/">
            <span class="level-start">
                <span class="level-item">SurfaceShader</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/mystudy/categories/Unity/">
            <span class="level-start">
                <span class="level-item">Unity</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/mystudy/categories/git/">
            <span class="level-start">
                <span class="level-item">git</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">3</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/mystudy/categories/shade学习/">
            <span class="level-start">
                <span class="level-item">shade学习</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">33</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/mystudy/categories/xlua/">
            <span class="level-start">
                <span class="level-item">xlua</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">1</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/mystudy/categories/网络同步/">
            <span class="level-start">
                <span class="level-item">网络同步</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">10</span>
            </span>
        </a></li><li>
        <a class="level is-marginless" href="/mystudy/categories/设计模式/">
            <span class="level-start">
                <span class="level-item">设计模式</span>
            </span>
            <span class="level-end">
                <span class="level-item tag">5</span>
            </span>
        </a></li>
            </ul>
        </div>
    </div>
</div>
    
        <div class="card widget">
    <div class="card-content">
        <div class="menu">
        <h3 class="menu-label">
            归档
        </h3>
        <ul class="menu-list">
        
        <li>
            <a class="level is-marginless" href="/mystudy/archives/2020/09/">
                <span class="level-start">
                    <span class="level-item">九月 2020</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">1</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/mystudy/archives/2020/07/">
                <span class="level-start">
                    <span class="level-item">七月 2020</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">23</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/mystudy/archives/2020/06/">
                <span class="level-start">
                    <span class="level-item">六月 2020</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">17</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/mystudy/archives/2020/03/">
                <span class="level-start">
                    <span class="level-item">三月 2020</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">2</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/mystudy/archives/2020/02/">
                <span class="level-start">
                    <span class="level-item">二月 2020</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">4</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/mystudy/archives/2019/09/">
                <span class="level-start">
                    <span class="level-item">九月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">5</span>
                </span>
            </a>
        </li>
        
        <li>
            <a class="level is-marginless" href="/mystudy/archives/2019/08/">
                <span class="level-start">
                    <span class="level-item">八月 2019</span>
                </span>
                <span class="level-end">
                    <span class="level-item tag">18</span>
                </span>
            </a>
        </li>
        
        </ul>
        </div>
    </div>
</div>
    
        
<div class="card widget">
    <div class="card-content">
        <h3 class="menu-label">
            标签云
        </h3>
        <a href="/mystudy/tags/game/" style="font-size: 15px;">game</a> <a href="/mystudy/tags/git/" style="font-size: 10px;">git</a> <a href="/mystudy/tags/学习/" style="font-size: 20px;">学习</a>
    </div>
</div>

    
    
        <div class="column-right-shadow is-hidden-widescreen is-sticky">
        
            
<div class="card widget" id="toc">
    <div class="card-content">
        <div class="menu">
            <h3 class="menu-label">
                目录
            </h3>
            <ul class="menu-list"><li>
        <a class="is-flex" href="#边缘检测">
        <span class="has-mr-6">1</span>
        <span>边缘检测</span>
        </a></li><li>
        <a class="is-flex" href="#卷积">
        <span class="has-mr-6">2</span>
        <span>卷积</span>
        </a><ul class="menu-list"><li>
        <a class="is-flex" href="#线性滤波">
        <span class="has-mr-6">2.1</span>
        <span>线性滤波</span>
        </a></li><li>
        <a class="is-flex" href="#卷积核">
        <span class="has-mr-6">2.2</span>
        <span>卷积核</span>
        </a></li><li>
        <a class="is-flex" href="#边缘检测算子">
        <span class="has-mr-6">2.3</span>
        <span>边缘检测算子</span>
        </a></li><li>
        <a class="is-flex" href="#Sobel算子">
        <span class="has-mr-6">2.4</span>
        <span>Sobel算子</span>
        </a></li><li>
        <a class="is-flex" href="#Laplacian算子">
        <span class="has-mr-6">2.5</span>
        <span>Laplacian算子</span>
        </a></li></ul></li><li>
        <a class="is-flex" href="#利用深度和法线纹理进行描边">
        <span class="has-mr-6">3</span>
        <span>利用深度和法线纹理进行描边</span>
        </a><ul class="menu-list"><li>
        <a class="is-flex" href="#Roberts算子">
        <span class="has-mr-6">3.1</span>
        <span>Roberts算子</span>
        </a></li></ul></li><li>
        <a class="is-flex" href="#法线外扩描边">
        <span class="has-mr-6">4</span>
        <span>法线外扩描边</span>
        </a></li></ul>
        </div>
    </div>
</div>

        
        </div>
    
</div>

                




<div class="column is-4-tablet is-4-desktop is-3-widescreen is-hidden-touch is-hidden-desktop-only has-order-3 column-right is-sticky">
    
        
<div class="card widget" id="toc">
    <div class="card-content">
        <div class="menu">
            <h3 class="menu-label">
                目录
            </h3>
            <ul class="menu-list"><li>
        <a class="is-flex" href="#边缘检测">
        <span class="has-mr-6">1</span>
        <span>边缘检测</span>
        </a></li><li>
        <a class="is-flex" href="#卷积">
        <span class="has-mr-6">2</span>
        <span>卷积</span>
        </a><ul class="menu-list"><li>
        <a class="is-flex" href="#线性滤波">
        <span class="has-mr-6">2.1</span>
        <span>线性滤波</span>
        </a></li><li>
        <a class="is-flex" href="#卷积核">
        <span class="has-mr-6">2.2</span>
        <span>卷积核</span>
        </a></li><li>
        <a class="is-flex" href="#边缘检测算子">
        <span class="has-mr-6">2.3</span>
        <span>边缘检测算子</span>
        </a></li><li>
        <a class="is-flex" href="#Sobel算子">
        <span class="has-mr-6">2.4</span>
        <span>Sobel算子</span>
        </a></li><li>
        <a class="is-flex" href="#Laplacian算子">
        <span class="has-mr-6">2.5</span>
        <span>Laplacian算子</span>
        </a></li></ul></li><li>
        <a class="is-flex" href="#利用深度和法线纹理进行描边">
        <span class="has-mr-6">3</span>
        <span>利用深度和法线纹理进行描边</span>
        </a><ul class="menu-list"><li>
        <a class="is-flex" href="#Roberts算子">
        <span class="has-mr-6">3.1</span>
        <span>Roberts算子</span>
        </a></li></ul></li><li>
        <a class="is-flex" href="#法线外扩描边">
        <span class="has-mr-6">4</span>
        <span>法线外扩描边</span>
        </a></li></ul>
        </div>
    </div>
</div>

    
    
</div>

            </div>
        </div>
    </section>
    <footer class="footer">
    <div class="container1">
        <div class="level1">
            <div class="level-start1 has-text-centered-mobile1">
                <a class="footer-logo is-block has-mb-6" href="/mystudy/">
                

                
                </a>
                <p class="is-size-7">
                &copy; 2020 Koliy&nbsp;
                Powered by <a href="https://github.com/koliy/koliy.github.io" target="_blank">Hexo</a> & <a
                        href="https://github.com/ppoffice/hexo-theme-icarus" target="_blank">Icarus</a>
                
                <br>
                <span id="busuanzi_container_site_uv">
                共<span id="busuanzi_value_site_uv">0</span>个访客
                </span>
                
                </p>
            </div>
            <div class="level-end1">
            
            </div>
        </div>
    </div>
</footer>
    <script src="https://cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/moment@2.22.2/min/moment-with-locales.min.js"></script>
<script>moment.locale("zh-CN");</script>

<script>
var IcarusThemeSettings = {
    article: {
        highlight: {
            clipboard: true,
            fold: 'unfolded'
        }
    }
};
</script>


    <script src="https://cdn.jsdelivr.net/npm/clipboard@2.0.4/dist/clipboard.min.js" defer></script>



    
    
    
    <script src="/mystudy/js/animation.js"></script>
    

    
    
    
    <script src="https://cdn.jsdelivr.net/npm/lightgallery@1.6.8/dist/js/lightgallery.min.js" defer></script>
    <script src="https://cdn.jsdelivr.net/npm/justifiedGallery@3.7.0/dist/js/jquery.justifiedGallery.min.js" defer></script>
    <script src="/mystudy/js/gallery.js" defer></script>
    

    
    

<div id="outdated">
    <h6>Your browser is out-of-date!</h6>
    <p>Update your browser to view this website correctly. <a id="btnUpdateBrowser" href="http://outdatedbrowser.com/">Update
            my browser now </a></p>
    <p class="last"><a href="#" id="btnCloseUpdateBrowser" title="Close">&times;</a></p>
</div>
<script src="https://cdn.jsdelivr.net/npm/outdatedbrowser@1.1.5/outdatedbrowser/outdatedbrowser.min.js" defer></script>
<script>
    document.addEventListener("DOMContentLoaded", function () {
        outdatedBrowser({
            bgColor: '#f25648',
            color: '#ffffff',
            lowerThan: 'flex'
        });
    });
</script>


    
    
<script src="https://cdn.jsdelivr.net/npm/mathjax@2.7.5/unpacked/MathJax.js?config=TeX-MML-AM_CHTML" defer></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
    MathJax.Hub.Config({
        'HTML-CSS': {
            matchFontHeight: false
        },
        SVG: {
            matchFontHeight: false
        },
        CommonHTML: {
            matchFontHeight: false
        },
        tex2jax: {
            inlineMath: [
                ['$','$'],
                ['\\(','\\)']
            ]
        }
    });
});
</script>

    
    

<a id="back-to-top" title="回到顶端" href="javascript:;">
    <i class="fas fa-chevron-up"></i>
</a>
<script src="/mystudy/js/back-to-top.js" defer></script>


    
    

    
    
    
    

    
    
    
    
    

    


<script src="/mystudy/js/main.js" defer></script>

    
    <div class="searchbox ins-search">
    <div class="searchbox-container ins-search-container">
        <div class="searchbox-input-wrapper">
            <input type="text" class="searchbox-input ins-search-input" placeholder="想要查找什么..." />
            <span class="searchbox-close ins-close ins-selectable"><i class="fa fa-times-circle"></i></span>
        </div>
        <div class="searchbox-result-wrapper ins-section-wrapper">
            <div class="ins-section-container"></div>
        </div>
    </div>
</div>
<script>
    (function (window) {
        var INSIGHT_CONFIG = {
            TRANSLATION: {
                POSTS: '文章',
                PAGES: '页面',
                CATEGORIES: '分类',
                TAGS: '标签',
                UNTITLED: '(无标题)',
            },
            CONTENT_URL: '/mystudy/content.json',
        };
        window.INSIGHT_CONFIG = INSIGHT_CONFIG;
    })(window);
</script>
<script src="/mystudy/js/insight.js" defer></script>
<link rel="stylesheet" href="/mystudy/css/search.css">
<link rel="stylesheet" href="/mystudy/css/insight.css"><!-- hexo-inject:begin --><!-- Begin: Injected MathJax -->
<script type="text/x-mathjax-config">
  MathJax.Hub.Config({"tex2jax":{"inlineMath":[["$","$"],["\\(","\\)"]],"skipTags":["script","noscript","style","textarea","pre","code"],"processEscapes":true},"TeX":{"equationNumbers":{"autoNumber":"AMS"}}});
</script>

<script type="text/x-mathjax-config">
  MathJax.Hub.Queue(function() {
    var all = MathJax.Hub.getAllJax(), i;
    for(i=0; i < all.length; i += 1) {
      all[i].SourceElement().parentNode.className += ' has-jax';
    }
  });
</script>

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js">
</script>
<!-- End: Injected MathJax -->
<!-- hexo-inject:end -->
    
</body>
</html>